package chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Chat Client class for ACE4.
 * @author derykegan
 *
 */
public class ChatClient extends Thread{

	ChatProtocol received, lastReceived;
	Socket sock;

	InputStream in = null;
	ObjectOutputStream oos = null;
	boolean threadActive = true;
	boolean debug = false;
	
	String username;				//the user's name
	ChatProtocol theMessage;		//packaged message
	
	Calendar calendar = new GregorianCalendar();
	SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
	
	ObjectInputStream ois;


	public ChatClient(boolean debug) throws IOException{
		this.debug = debug;
		try {
			System.out.println("CLIENT------------------");
			System.out.println("Client started.");
			
			/* prompt for username */
			System.out.println("\nPlease enter username:");

			BufferedReader stdIn = new BufferedReader(
					new InputStreamReader(System.in));
			username = stdIn.readLine();

			System.out.println("Thanks, " + username + "!");

			/* open socket */
			sock = new Socket("127.0.0.1",9399);
			if(debug)
				System.out.println("Socket opened.");

			/* set up input and output objects */

			oos = new ObjectOutputStream
					(sock.getOutputStream());
			
			in = sock.getInputStream();
			ois = new ObjectInputStream(in);
			
			(new Thread(this)).start();
			
			if(debug)
				System.out.println("waiting for welcome");
			
			
			/* --- main chat loop --- */
			boolean executing = true;

			while(executing){
				String input = null;
				ChatProtocol messageRead = null;
				
				if(received != null)
					if(received != lastReceived){
						messageRead = received;
						lastReceived = received;
					}
				

				/* check if we have received a message from server */
				if(messageRead != null){
					
					if(debug)
						System.out.println("CLIENT - MESSAGE RECEIVED FROM SERVER");
					
					/* check type of message ...*/

					/* if server has shut down */
					if(messageRead.getState() == ChatProtocol.SERVER_DISCONNECT){
						System.out.println("Server disconnected, shutting down.");
						executing = false;
						break;
					}

					/* if server has sent a status message */
					if(messageRead.getState() == ChatProtocol.SERVER_STATUS_MESSAGE){
						System.out.printf("SERVER MESSAGE: ");
						System.out.println(messageRead.getMessage().getTime() +
								" " + 
								messageRead.getMessage().getMessageText());
					}

					/* if we have a new chat message */
					if(messageRead.getState() == ChatProtocol.MESSAGE_FROM_SERVER){
						Message m = messageRead.getMessage();
						System.out.printf(m.getTime() + " " + 
								m.getUsername() + ": ");
						System.out.println(m.getMessageText());
					}

				}

				/* check if user has input a message */
				if(stdIn.ready())
					input = stdIn.readLine();

				if(input != null){
					if(debug)
						System.out.println("CLIENT - NEW MESSAGE INPUT");
					
					/* update to current system time */
					calendar = GregorianCalendar.getInstance();
					
					Message newMessage = new Message(
							format.format(calendar.getTime()),
							username,
							input);
					/* write message to socket */
					oos.writeObject(new ChatProtocol(
							ChatProtocol.MESSAGE_TO_SERVER,
							newMessage));
					oos.flush();
					if(debug)
						System.out.println("CLIENT - MESSAGE WRITTEN");
				}
				
				/* give other threads a chance to execute */
				Thread.sleep(200);
			}

			/* no longer executing */

		}
		catch (Exception e) {
			System.err.println("Error: " + e);
		}
		
		finally {
			/* write message to socket */
			oos.writeObject(new ChatProtocol(
					ChatProtocol.CLIENT_DISCONNECT,
					null));
			oos.flush();
			
			in.close();
			sock.close();
			System.out.println("\nClient shutdown.");
		}
	}

	@Override
	public void run() {
		threadActive = true;
		try{
			while(threadActive){
				received = (ChatProtocol) ois.readObject();
				Thread.sleep(2000);
			}
		}
		catch(Exception e){
			System.out.println("Error: " + e);
		}
	}
}
